/**
 * @file sender.c
 * Betriebssysteme - Beispiel 3
 *
 * @author Christian Lachner <ic11b010@technikum-wien.at>
 * @author Max Paflik <ic11b006@technikum-wien.at>
 * @date 2012/06/03
 *
 * @version $Revision: 7 $
 *
 * URL: $HeadURL$
 *
 * Last Modified: $Author: Chris $
 */

#include "myrxtx.h"

int main(int argc, char * argv[]) {
	int bufsize;
	int semid_r = -1;
	int semid_w = -1;
	int shmid = -1;
	int * shmptr = NULL;
	int i = 0;
	int j = 0;
#if DEBUG > 0
	unsigned int bytecount = 0;
#endif

	if((bufsize = handle_params(argc, argv)) != MYRXTX_ERROR) {
		/* init/grab write-semaphore and fetch it's id */
		if((semid_w = init_sem(SEMKEY_W, bufsize)) == -1) {
			cleanup(&semid_r, &semid_w, &shmid, shmptr);
			return EXIT_FAILURE;
		}

		/* init/grab read-semaphore and fetch it's id */
		if((semid_r = init_sem(SEMKEY_R, 0)) == MYRXTX_ERROR) {
			cleanup(&semid_r, &semid_w, &shmid, shmptr);
			return EXIT_FAILURE;
		}

		/* init/grab SHM and fetch it's id */
		if((shmid = init_shm(SHMKEY, bufsize)) == MYRXTX_ERROR) {
			cleanup(&semid_r, &semid_w, &shmid, shmptr);
			return EXIT_FAILURE;
		}

		/* attach SHM segment */
		if((shmptr = shmat(shmid, NULL, 0)) == (void *) -1) {
			print_error_eno(errno);
			cleanup(&semid_r, &semid_w, &shmid, shmptr);
			return EXIT_FAILURE;
		}

#if DEBUG > 0
		fprintf(stderr, "DEBUG: TX = t\n");
#endif

		do {
			j = fgetc(stdin);

			/* waits for the semaphore */
			while(P(semid_w) == -1) {
				if(errno != EINTR) {
					print_error_msg("Error while waiting for the writing semaphore!");
					cleanup(&semid_r, &semid_w, &shmid, shmptr);
					return EXIT_FAILURE;
				}
#if DEBUG > 0
				else {
					fprintf(stderr, "DEBUG: %s: Process interruped! waiting...\n", thisfname);
				}
#endif
			}

			shmptr[i] = j;

			/* signals to the semaphore */
			if(V(semid_r) == -1) {
				print_error_msg("Error while sending signals to reading semaphore!");
				cleanup(&semid_r, &semid_w, &shmid, shmptr);
				return EXIT_FAILURE;
			}

			i++;

#if DEBUG > 0
			bytecount++;
			if(bytecount % DEBUG_BC_DIVISOR == 0) {
				fprintf(stderr, "s");
				fflush(stderr);
				bytecount = 0;
			}
#endif

			if(i >= bufsize) {
				i = 0;
			}
		} while (j != EOF);

#if DEBUG > 0
		fprintf(stderr, "?");
		fflush(stderr);
#endif

		/* check if eof was legit or failure */
		if(ferror(stdin)) {
			print_error_msg("Error while reading from stdin!");
			cleanup(&semid_r, &semid_w, &shmid, shmptr);
			return EXIT_FAILURE;
		}

		/* detach shared memory segments */
		if(shmdt(shmptr) == -1) {
			/* no cleanups neccessary */
			print_error_eno(errno);
			return EXIT_FAILURE;
		}
	} else {
		print_usage();
		return EXIT_FAILURE;
	}

	return EXIT_SUCCESS;
}
